Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit b60eab0fcf35dd18c6610d8e5f2a81308e7db291


Parents : 17310fc
Author : Mark Qvist <bc7291552be7a58f361522990465165c>
Date : 2026-04-28T19:07:02+02:00

Added rngit server-side handling for direct ref updates

Changes

1 files changed, 36 insertions(+), 2 deletions(-)


Diff

diff --git a/RNS/Utilities/rngit/server.py b/RNS/Utilities/rngit/server.py
index e0a92845..6c89d51e 100644
--- a/RNS/Utilities/rngit/server.py
+++ b/RNS/Utilities/rngit/server.py
@@ -602,8 +602,42 @@ class ReticulumGitNode():
return self.RES_REMOTE_FAIL.to_bytes(1, "big") + str(e).encode("utf-8")
elif operations:
- # TODO: Implement
- pass
+ if not type(operations) == list: return self.RES_INVALID_REQ.to_bytes(1, "big") + b"Invalid data for operations"
+
+ try:
+ for op in operations:
+ action = op.get("action", "")
+ ref = op.get("ref", "")
+ sha = op.get("sha", "")
+ op_force = op.get("force", False)
+
+ if action != "update_ref": return self.RES_INVALID_REQ.to_bytes(1, "big") + f"Unknown operation: {action}".encode("utf-8")
+ if not ref.startswith("refs/"): return self.RES_INVALID_REQ.to_bytes(1, "big") + b"Invalid ref"
+ if not sha or len(sha) < 40: return self.RES_INVALID_REQ.to_bytes(1, "big") + b"Invalid SHA"
+
+ # Verify the target object exists in the repository
+ cat_result = subprocess.run(["git", "cat-file", "-t", sha], cwd=repository_path, capture_output=True, check=False)
+ if cat_result.returncode != 0: return self.RES_REMOTE_FAIL.to_bytes(1, "big") + f"Object {sha} does not exist in repository".encode("utf-8")
+
+ # Check force flag: If the ref already exists and
+ # points to a different SHA, the push must be forced.
+ rev_result = subprocess.run(["git", "rev-parse", ref], cwd=repository_path, capture_output=True, text=True, check=False)
+ if rev_result.returncode == 0:
+ existing_sha = rev_result.stdout.strip()
+ if existing_sha != sha and not op_force:
+ return self.RES_DISALLOWED.to_bytes(1, "big") + f"Ref {ref} already exists at different SHA (force required)".encode("utf-8")
+
+ RNS.log(f"Updating ref {ref} to {sha} in {group_name}/{repository_name}", RNS.LOG_DEBUG)
+ execv = ["git", "update-ref", ref, sha]
+ result = subprocess.run(execv, cwd=repository_path, capture_output=True, check=False)
+
+ if result.returncode != 0: return self.RES_REMOTE_FAIL.to_bytes(1, "big") + result.stderr
+
+ return b"\x00"
+
+ except Exception as e:
+ RNS.log(f"Error while handling push operations for {group_name}/{repository_name}: {e}", RNS.LOG_ERROR)
+ return self.RES_REMOTE_FAIL.to_bytes(1, "big") + str(e).encode("utf-8")
else: return self.RES_INVALID_REQ.to_bytes(1, "big") + b"Invalid request data"


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────